#include "StdAfx.h"
#define BOOST_TEST_MODULE Aggregator test
#include <boost/test/unit_test.hpp>
#include "Parser.h"
#include "SearchManager.h"

BOOST_AUTO_TEST_CASE( PartTest )
{

   PartPtr part1 = Part::Create("1: 2 3 4 5 6 7");

   BOOST_CHECK_EQUAL(part1->ToString(), "1: 2 3 4 5 6 7");
   
   PartPtr part2 = Part::Create("122: 142 53 64 75 86 87");

   BOOST_CHECK_EQUAL(part2->ToString(), "122: 142 53 64 75 86 87");

   BOOST_CHECK(part2->GetID() == 122);

   // wrong format
   BOOST_CHECK(Part::Create("asd1: 2 3 4 5 67") == PartPtr());

   BOOST_CHECK(Part::Create("1: 2 3 33 4 5 6 7") == PartPtr());

   //overflow
   BOOST_CHECK(Part::Create("12222222222222222222: 2 3 33 4 5 6 7") == PartPtr());

   // duplicates
   //BOOST_CHECK(Part::Create("1: 2 3 3 5 6 7") == PartPtr());

}

BOOST_AUTO_TEST_CASE( AggregatorTest )
{
   BOOST_CHECK(Aggregator::Create("123444asd") == AggregatorPtr());

   AggregatorPtr aggregator1 = Aggregator::Create("123444");
   BOOST_CHECK(aggregator1 != AggregatorPtr());

   aggregator1->AddPart(Part::Create("1: 2 3 4 5 6 7"));
   aggregator1->AddPart(Part::Create("12: 23 34 45 56 67 7"));
   aggregator1->AddPart(Part::Create("13: 62 35 4 55 64 73"));
   aggregator1->AddPart(Part::Create("15: 244 33 423 5324 634 733"));
   aggregator1->AddPart(Part::Create("15: 244 33 423 5324 634 733 sadasd")); 
   //id duplicates
   //aggregator1->AddPart(Part::Create("13: 62 35 4 55 64 73"));

   BOOST_CHECK(aggregator1->GetParts().size() == 4);

   BOOST_CHECK_EQUAL(aggregator1->ToString(), std::string("123444\n")
                                            + std::string("1: 2 3 4 5 6 7\n")
                                            + std::string("12: 23 34 45 56 67 7\n")
                                            + std::string("13: 62 35 4 55 64 73\n")
                                            + std::string("15: 244 33 423 5324 634 733\n")
                                            );
}

BOOST_AUTO_TEST_CASE( StorageTest )
{
   AggregatorPtr aggregator1 = Aggregator::Create("1");
   aggregator1->AddPart(Part::Create("1: 2 3 4 5 6 7", aggregator1));
   aggregator1->AddPart(Part::Create("12: 23 34 45 56 67 71", aggregator1));
   aggregator1->AddPart(Part::Create("13: 62 35 4 55 64 73", aggregator1));
   aggregator1->AddPart(Part::Create("15: 244 33 423 5324 634 733", aggregator1));

   AggregatorPtr aggregator2 = Aggregator::Create("2");
   aggregator2->AddPart(Part::Create("16: 26 36 46 56 6 7", aggregator2));
   aggregator2->AddPart(Part::Create("122: 23 33 44 58 67 71", aggregator2));
   aggregator2->AddPart(Part::Create("132: 621 325 43 553 64 73", aggregator2));
   aggregator2->AddPart(Part::Create("152: 244 33 423 53 634 73", aggregator2));

   Storage storage;

   storage.Add(aggregator1);
   storage.Add(aggregator2);

   PartsList parts = storage.GetParts(23);
   BOOST_CHECK(parts.size() == 2);

   BOOST_CHECK(storage.GetParts(2333) == PartsList());

   // Searcher

   SearchProperties props(3, 5);
/*   Searcher engine(props, storage);
   
   PartPtr keyword1 = Part::Create("15: 1 2 423 53 634 73");

   AggregatorList aggrs1 = engine.GetAggregators(keyword1->GetSignature());
   BOOST_CHECK(aggrs1.size() == 1);

   PartPtr keyword2 = Part::Create("15: 71 23 33 44 58 67");
   AggregatorList aggrs2 = engine.GetAggregators(keyword2->GetSignature());
   BOOST_CHECK(aggrs2.size() == 2);

   // nothing is found
   PartPtr keyword3 = Part::Create("15: 100 200 300 400 500 600");
   AggregatorList aggrs3 = engine.GetAggregators(keyword3->GetSignature());
   BOOST_CHECK(aggrs3.size() == 0);
*/

   // SearchManager

   SearchManager manager(props, storage);

   PartPtr keyword1 = Part::Create("15: 1 2 423 53 634 73");
   BOOST_CHECK_EQUAL(manager.ProcessRequest(keyword1), std::string("Looking for:15: 1 2 423 53 634 73\n")
                                                     + std::string("Found 1\n")
                                                     + std::string("-------------------------------------------------\n")
                                                     + std::string("2\n")
                                                     + std::string("16: 26 36 46 56 6 7\n")
                                                     + std::string("122: 23 33 44 58 67 71\n")
                                                     + std::string("132: 621 325 43 553 64 73\n")
                                                     + std::string("152: 244 33 423 53 634 73\n")
                                                     );

   PartPtr keyword2 = Part::Create("15: 71 23 33 44 58 67");
   BOOST_CHECK_EQUAL(manager.ProcessRequest(keyword2), std::string("Looking for:15: 71 23 33 44 58 67\n")
                                                     + std::string("Found 2\n")
                                                     + std::string("-------------------------------------------------\n")
                                                     + std::string("1\n")
                                                     + std::string("1: 2 3 4 5 6 7\n")
                                                     + std::string("12: 23 34 45 56 67 71\n")
                                                     + std::string("13: 62 35 4 55 64 73\n")
                                                     + std::string("15: 244 33 423 5324 634 733\n")
                                                     + std::string("-------------------------------------------------\n")
                                                     + std::string("2\n")
                                                     + std::string("16: 26 36 46 56 6 7\n")
                                                     + std::string("122: 23 33 44 58 67 71\n")
                                                     + std::string("132: 621 325 43 553 64 73\n")
                                                     + std::string("152: 244 33 423 53 634 73\n")
                                                     );

   PartPtr keyword3 = Part::Create("15: 100 200 300 400 500 600");
   BOOST_CHECK_EQUAL(manager.ProcessRequest(keyword3), std::string("Looking for:15: 100 200 300 400 500 600\n")
                                                     + std::string("Nothing found\n")
                                                     );

}

BOOST_AUTO_TEST_CASE( ParsingTest )
{
   const Storage store = DataParser::Parse("data.txt", &Storage::Add);
   BOOST_CHECK(store.size() > 0);

   const PartsList parts = CaseParser::Parse("cases.txt", &PartsList::push_back);
   BOOST_CHECK(parts.size() > 0);
   

}